home *** CD-ROM | disk | FTP | other *** search
/ Die Speccy' 97 / Die Speccy' 97.iso / amiga_system / the_aminet / comm / bbs / s342q07.lha / netcache.c < prev    next >
C/C++ Source or Header  |  1994-12-24  |  17KB  |  711 lines

  1. /*
  2. *       netcache.c
  3. *
  4. * Networking functions for handling network cache (fast transfers).
  5. */
  6. /*
  7. *       history
  8. *
  9. * 91Sep20 HAW Created.
  10. */
  11. #include "ctdl.h"
  12. #define MAP_FILE  "map.$$$"
  13. #define FAST_TEMPLATE "fast$$$.%s"
  14. #define NETMSGS   "netmsgs.%s"
  15. /*
  16. *       contents
  17. *
  18. */
  19. char RecMassTransfer;
  20. char MassTransferSent;
  21. char Zmodem = 0;
  22. static int MTCompVal;
  23.  
  24.  
  25. extern char logNetResults;
  26. extern char netDebug;
  27.  
  28.  
  29. extern CONFIG    cfg;   /* Lots an lots of variables    */
  30. extern char      *SR_Sent;
  31. extern MessageBuffer   msgBuf;
  32. extern char      inReceive;
  33. extern NetBuffer netTemp;
  34. extern char      inNet;
  35. extern NetBuffer netBuf;
  36. extern FILE  *netLog;
  37. extern rTable    *roomTab;
  38. extern FILE  *upfd;
  39. extern int   callSlot;
  40. extern NetTable  *netTab;
  41. extern int       thisNet;
  42. extern char  *READ_ANY, *APPEND_ANY;
  43. /*
  44. * FileMap
  45. *
  46. * This structure is used to map between a filename and the room it's
  47. * carrying.
  48. */
  49. typedef struct
  50.   {
  51.   char *FileName;
  52.   char *RoomName;
  53.  
  54.   }
  55. FileMap;
  56. /*
  57. * Mappings
  58. *
  59. * This is a list of mappings for our current work.
  60. */
  61. static void FreeMapping();
  62. SListBase Mappings =
  63.   {
  64.   NULL, NULL, NULL, FreeMapping, NULL
  65.  
  66.   };
  67. /*
  68. * SendFastTransfer()
  69. *
  70. * We want to use Facility 21, the mass transfer of messages.
  71. */
  72. char SendFastTransfer()
  73.   {
  74.   long   size;
  75.   extern long netBytes;
  76.   extern AN_UNSIGNED RecBuf[SECTSIZE + 5];
  77.   struct cmd_data cmds;
  78.   char BaseArcName[15], Outgoing;
  79.   int protocol;
  80.   char ArcFileName[100];
  81.   char CacheDir[70];
  82.   int RoomOutgoing(SharedRoom *room, int system, int index, int roomslot,  char *d);
  83.   int UnCacheRoom(SharedRoom *room, int system, int index, int roomslot,  void *d);
  84.   if (!netBuf.nbflags.MassTransfer)
  85.     {
  86.     if ( netDebug )splitF(netLog, "SendFastTransfer:FALSE, No flag set\n");
  87.     return FALSE;
  88.  
  89.     }
  90.   if (!netBuf.nbflags.local &&
  91.   !(netBuf.nbflags.spine || inReceive))
  92.     {
  93.     if ( !netBuf.nbflags.local && netDebug)splitF(netLog, "SendFastTransfer:FALSE, Not Local\n");
  94.     if (  netBuf.nbflags.spine && netDebug)splitF(netLog, "SendFastTransfer:FALSE, A Spine\n");
  95.     if (             inReceive && netDebug)splitF(netLog, "SendFastTransfer:FALSE, We have been called\n");
  96.     splitF(netLog, "Mass Transfer flag ignored\n");
  97.     return FALSE;
  98.  
  99.     }
  100.   if (!CompAvailable(GetCompression(thisNet)))
  101.     {
  102.     if (netDebug)splitF(netLog, "SendFastTransfer:FALSE, No compression set\n");
  103.     return FALSE;
  104.  
  105.     }
  106.   /* do we have rooms to send??? */
  107.   Outgoing = FALSE;
  108.   EachSharedRoom(thisNet, RoomOutgoing, VirtualRoomOutgoing, &Outgoing);
  109.   if (!Outgoing)
  110.     {
  111.     MassTransferSent = TRUE;
  112.     EachSharedRoom(thisNet, UnCacheRoom, UnCacheVirtualRoom, NULL);
  113.     if (netDebug)splitF(netLog, "SendFastTransfer:FALSE, No rooms to send\n");
  114.     return FALSE;
  115.  
  116.     }
  117.   zero_struct(cmds);
  118.   sPrintf(cmds.fields[0], "%d", GetCompression(thisNet));
  119.   sPrintf(cmds.fields[1], "%d", ZM_PROTOCOL);
  120.   strCpy(cmds.fields[2], "0");
  121.   strCpy(cmds.fields[3], "-1");
  122.   cmds.command = FAST_MSGS;
  123.   protocol = ZM_PROTOCOL;
  124.   if (!Zmodem || FindProtocolCode(Zmodem, FALSE) == -1 ||
  125.   !sendNetCommand(&cmds, "mt"))
  126.     {
  127.     sPrintf(cmds.fields[1], "%d", DEFAULT_PROTOCOL);
  128.     protocol = DEFAULT_PROTOCOL;
  129.     if (!sendNetCommand(&cmds, "mt"))
  130.       {
  131.       if( logNetResults && netDebug )splitF(netLog, "Fast Transfer refused\n");
  132.       return FALSE;
  133.  
  134.       }
  135.  
  136.     }
  137.   if (SendMapFile())
  138.     {
  139.     if (!MapFileAccepted())
  140.       {
  141.       if (netDebug)splitF(netLog, "SendFastTransfer:FALSE, MAP File problem\n");
  142.       return FALSE;
  143.  
  144.       }
  145.     CacheSystem(thisNet, FALSE);
  146.     outMod(ACK);
  147.     sPrintf(BaseArcName, NETMSGS, CompExtension(GetCompression(thisNet)));
  148.     NetCacheName(ArcFileName, thisNet, BaseArcName);
  149.     if( logNetResults && netDebug )splitF(netLog, "Mass Transfer\n");
  150.     if (netDebug)splitF(netLog, "ArcFileName:%s\n",ArcFileName);
  151.     if (protocol == DEFAULT_PROTOCOL)
  152.     SendHostFile(ArcFileName);
  153.     else
  154.       {
  155.       ExternalTransfer(FindProtocolCode(Zmodem, FALSE), ArcFileName);
  156.       while (MIReady()) inp();
  157.       pause(80);   /* keep the other system from eating our NAK */
  158.  
  159.       }
  160.     if (gotCarrier())
  161.       {
  162.       ITL_Receive(NULL, FALSE, TRUE, putFLChar, fclose);
  163.       if (RecBuf[0] == BAD || !gotCarrier())
  164.         {
  165.         if (netDebug)splitF(netLog, "SendFastTransfer:FALSE, lost carrier, or bad transmission\n");
  166.         return FALSE;
  167.         };
  168.       MassTransferSent = TRUE;
  169.       EachSharedRoom(thisNet, UnCacheRoom, UnCacheVirtualRoom, NULL);
  170.       MakeNetCacheName(CacheDir, thisNet);
  171.       if (netDebug)splitF(netLog, "CacheDir:%s\n",CacheDir);
  172.       if (ChangeToCacheDir(CacheDir) == 0)
  173.         {
  174.         netBytes = 0l;
  175.         wildCard(getSize, BaseArcName, FALSE, "", FALSE);
  176.         size = netBytes;
  177.         netBytes = 0l;
  178.         wildCard(getSize, CACHED_FILES, FALSE, "", FALSE);
  179.         wildCard(DelFile, ALL_FILES, FALSE, "", FALSE);
  180.         if( logNetResults && netDebug )splitF(netLog, "MT: %ld => %ld\n", netBytes, size);
  181.  
  182.         }
  183.       homeSpace();
  184.       return TRUE;
  185.  
  186.       }
  187.  
  188.     }
  189.   if (netDebug)splitF(netLog, "SendFastTransfer:FALSE, problem with sendmapfile()\n");
  190.   return FALSE;
  191.  
  192.   }
  193. /*
  194. * RoomOutgoing()
  195. *
  196. * This is responsible for deciding if the given shared room has outgoing
  197. * material in a room eligible for mass transfers.
  198. */
  199. int RoomOutgoing(SharedRoom *room, int system, int index, int roomslot,
  200. char *d)
  201.   {
  202.   if (strLen(roomTab[roomslot].rtname) && HasOutgoing(system, index))
  203.     {
  204.     *d = TRUE;
  205.     return ERROR;
  206.  
  207.     }
  208.   return TRUE;
  209.  
  210.   }
  211. /*
  212. * SendMapFile()
  213. *
  214. * This sends a file containing the names of rooms to share and the filenames
  215. * in the upcoming archive file to map the rooms to.  Format is a series of
  216. * pairs of lines (UNIX style), first the roomname and then the filename.
  217. * blank line signals end of file.
  218. */
  219. char SendMapFile()
  220.   {
  221.   int NormalRoomMap(SharedRoom *room, int system, int index, int roomslot,
  222.   void *d);
  223.   if (!ITL_Send(STARTUP)) return FALSE;
  224.   EachSharedRoom(thisNet, NormalRoomMap, VirtualRoomMap, NULL);
  225.   ITL_Line("");
  226.   return ITL_Send(FINISH);
  227.  
  228.   }
  229. /*
  230. * NormalRoomMap()
  231. *
  232. * This sends the given room's name and cache file name if there is an
  233. * outgoing file pending or one will be built.
  234. */
  235. int NormalRoomMap(SharedRoom *room, int system, int index, int roomslot,
  236. void *d)
  237.   {
  238.   char work[20];
  239.   if (strLen(roomTab[roomslot].rtname) && HasOutgoing(system, index))
  240.     {
  241.     ITL_Line(roomTab[roomslot].rtname);
  242.     sPrintf(work, CACHE_END_NAME, roomslot);
  243.     ITL_Line(work);
  244.  
  245.     }
  246.   return TRUE;
  247.  
  248.   }
  249. /*
  250. * ITL_Line()
  251. *
  252. * Sends the specified line to the SendITLchar function.
  253. */
  254. void ITL_Line(char *data)
  255.   {
  256.   while (*data)
  257.     {
  258.     sendITLchar((int) *data);
  259.     data++;
  260.  
  261.     }
  262.   sendITLchar((int) '\n');
  263.  
  264.   }
  265. /*
  266. * DelFile()
  267. *
  268. * This function kills the named file.
  269. */
  270. void DelFile(DirEntry *f)
  271.   {
  272.   unlink(f->unambig);
  273.  
  274.   }
  275. /*
  276. * MapFileAccepted()
  277. *
  278. * This function is responsible for discovering if the map file is acceptable.
  279. */
  280. char MapFileAccepted()
  281.   {
  282.   FILE *fd;
  283.   char toReturn = TRUE, work[NAMESIZE + 5];
  284.   ToTempArea();
  285.   if (ITL_Receive("moo", FALSE, TRUE, putFLChar, fclose) == ITL_SUCCESS)
  286.     {
  287.     if ((fd = safeopen("moo", READ_ANY)) == NULL)
  288.     toReturn = FALSE;
  289.     else
  290.       {
  291.       GetAString(work, sizeof work, fd);
  292.       if (strLen(work) != 0) toReturn = FALSE;
  293.       fclose(fd);
  294.       unlink("moo");
  295.  
  296.       }
  297.  
  298.     }
  299.   else toReturn = FALSE;
  300.   KillTempArea();
  301.   return toReturn;
  302.  
  303.   }
  304. #define TOP_COMP  4
  305. /*
  306. * netFastTran()
  307. *
  308. * Accept an archive of files?
  309. */
  310. void netFastTran(struct cmd_data *cmds)
  311.   {
  312.   char CheckMap(char *fn, char talk);
  313.   int MTProtocol;
  314.   SYS_FILE fn;
  315.   char work[15];
  316.   MTCompVal  = atoi(cmds->fields[0]);
  317.   MTProtocol = atoi(cmds->fields[1]);
  318.   if (RecMassTransfer || MTCompVal > TOP_COMP || MTCompVal < 0 ||
  319.   !DeCompAvailable(MTCompVal))
  320.     {
  321.     reply(BAD, "nope");
  322.     return;
  323.  
  324.     }
  325.   if (MTProtocol == ZM_PROTOCOL)
  326.     {
  327.     if (!Zmodem || FindProtocolCode(Zmodem, TRUE) == -1)
  328.       {
  329.       reply(BAD, "No protocol");
  330.       return;
  331.  
  332.       }
  333.  
  334.     }
  335.   else if (MTProtocol != DEFAULT_PROTOCOL)
  336.     {
  337.     reply(BAD, "No protocol");
  338.     return;
  339.  
  340.     }
  341.   if (strCmp(cmds->fields[2], "0") != SAMESTRING ||
  342.   strCmp(cmds->fields[3], "-1") != SAMESTRING)
  343.     {
  344.     reply(BAD, " Field 2 & Field 3 no match");
  345.     return;
  346.  
  347.     }
  348.   reply(GOOD, "");
  349.   makeSysName(fn, MAP_FILE, &cfg.netArea);
  350.   if (netDebug)splitF(netLog, "MAP File:%s\n",fn);
  351.   if (ITL_Receive(fn, FALSE, TRUE, putFLChar, fclose) != ITL_SUCCESS)
  352.     {
  353.     return ;
  354.  
  355.     }
  356.   KillList(&Mappings);
  357.   if (CheckMap(fn, TRUE))
  358.     {
  359.     splitF(netLog, "Accepting mass transfer %d\n", MTProtocol);
  360.     if (receive(120) == NAK) return;
  361.  
  362.     sPrintf(work, FAST_TEMPLATE, CompExtension(MTCompVal));  /*** bug fix ***/
  363. /*    makeSysName(fn, work, &cfg.netArea); */
  364.     ChangeToCacheDir(&cfg.netArea);           /*** bug fix ***/
  365.  
  366.     if (netDebug)splitF(netLog, "AMT File(netarea):%s\n",work);
  367.     if (MTProtocol == DEFAULT_PROTOCOL)
  368.       {
  369.       if (netDebug)splitF(netLog, "Protocol: DEFAULT\n",work);
  370.       if (ITL_Receive(work,FALSE,TRUE, putFLChar, fclose) != ITL_SUCCESS)
  371.         {
  372.         return ;
  373.  
  374.         }
  375.  
  376.       }
  377.     else if (MTProtocol == ZM_PROTOCOL)
  378.       {
  379.       if (netDebug)splitF(netLog, "Protocol: Zmodem/External\n",work);
  380.       ExternalTransfer(FindProtocolCode(Zmodem, TRUE), work);
  381.       while (MIReady()) inp();
  382.  
  383.       }
  384.     if (access(fn, 0) == 0 )
  385.       {
  386.       reply(GOOD, "");
  387.       /* recovery setup in case of power failure, etc */
  388.       sPrintf(fn, "%s:%d", FAST_TRANS_FILE, MTCompVal);
  389.       UpdateRecoveryFile(fn);
  390.       RecMassTransfer = TRUE;
  391.       }
  392.     else
  393.       {
  394.       reply(BAD, "No file");
  395.       if( logNetResults )splitF(netLog, "File not received:%s\n",fn);
  396.       makeSysName(fn, MAP_FILE, &cfg.netArea);
  397.       unlink(fn);
  398.  
  399.       }
  400.  
  401.     }
  402.   homeSpace();
  403.   }
  404. /*
  405. * CheckMap()
  406. *
  407. * Checks the map of room names to see if we refuse any.
  408. */
  409. char CheckMap(char *fn, char talk)
  410.   {
  411.   FILE *fd;
  412.   char work[2 * NAMESIZE];
  413.   char toReturn = TRUE, bad;
  414.   FileMap *data;
  415.   RoomSearch arg;
  416.   if (talk && !ITL_Send(STARTUP)) return FALSE;
  417.   if ((fd = safeopen(fn, READ_ANY)) != NULL)
  418.     {
  419.     while (GetAString(work, sizeof work, fd) != NULL)
  420.       {
  421.       bad = TRUE;
  422.       if (strLen(work) == 0) break;
  423.       if (strLen(work) < NAMESIZE)
  424.         {
  425.         strCpy(arg.Room, work);
  426.         if (RoomRoutable(&arg))
  427.           {
  428.           bad = FALSE;
  429.           data = GetDynamic(sizeof *data);
  430.           data->RoomName = strdup(work);
  431.           GetAString(work, sizeof work, fd);
  432.           data->FileName = strdup(work);
  433.           if (netDebug)splitF(netLog, "MAP Data:RoomName:%s FileName:%s\n"
  434.           ,data->RoomName, data->FileName);
  435.           AddData(&Mappings, data, NULL, FALSE);
  436.  
  437.           }
  438.  
  439.         }
  440.       /* this form lets us respond to several errors with one chunk of code */
  441.       if (bad)
  442.         {
  443.         toReturn = FALSE;
  444.         if (talk) ITL_Line(work);
  445.         GetAString(work, sizeof work, fd);
  446.  
  447.         }
  448.  
  449.       }
  450.     fclose(fd);
  451.  
  452.     }
  453.   else
  454.     {
  455.     printf("Couldn't open %s!\n", fn);
  456.     if (talk) ITL_Line("moo");
  457.     toReturn = FALSE;
  458.  
  459.     }
  460.   if (talk)
  461.     {
  462.     ITL_Line("");
  463.     ITL_Send(FINISH);
  464.  
  465.     }
  466.   return toReturn;
  467.  
  468.   }
  469. /*
  470. * FreeMapping()
  471. *
  472. * Frees a mapping structure.
  473. */
  474. static void FreeMapping(FileMap *data)
  475.   {
  476.   free(data->FileName);
  477.   free(data->RoomName);
  478.   free(data);
  479.  
  480.   }
  481. /*
  482. * KillCacheFiles()
  483. *
  484. * This function kills all cache information concerning a node.  It is called
  485. * when a node is deleted from the nodelist, NOT when caching is simply turned
  486. * off.
  487. */
  488. void KillCacheFiles(int which)
  489.   {
  490.   char ArcFileName[100];
  491.   MakeNetCacheName(ArcFileName, which);
  492.   /* we check this due to the statement after - kill all files! */
  493.   if (ChangeToCacheDir(ArcFileName) == 0)
  494.   wildCard(DelFile, ALL_FILES, FALSE, "", FALSE);
  495.   homeSpace();
  496.   rmdir(ArcFileName);
  497.  
  498.   }
  499. /*
  500. * ReadFastFiles()
  501. *
  502. * This function reads in all of the messages from an Arc file.
  503. */
  504. void ReadFastFiles()
  505.   {
  506.   SYS_FILE fn;
  507.   char work[15];
  508.   void EatMsgFile();
  509.   if (!RecMassTransfer) return;
  510.   RecMassTransfer = FALSE;
  511.   sprintf(work, FAST_TEMPLATE, CompExtension(MTCompVal));
  512.   makeSysName(fn, work, &cfg.netArea);
  513.   if (netDebug)splitF(netLog, "RFF:%s(netarea)\n",fn);
  514.   NetDeCompress(MTCompVal, fn);
  515.   RunList(&Mappings, EatMsgFile);
  516.   KillNetDeCompress();
  517.   unlink(fn);
  518.   makeSysName(fn, MAP_FILE, &cfg.netArea);
  519.   unlink(fn);
  520.   KillList(&Mappings);
  521.   homeSpace();
  522.   }
  523. /*
  524. * EatMsgFile()
  525. *
  526. * This eats a message file extracted from an archive file.
  527. */
  528. void EatMsgFile(FileMap *data)
  529.   {
  530.   char fn[80];
  531.   char vfn[70];
  532.   int VirtNo;
  533.   RoomSearch arg;
  534.   extern char *SharingRefusal[];
  535.   strCpy(arg.Room, data->RoomName);
  536.   if (!RoomRoutable(&arg))
  537.     {
  538.     if( logNetResults )splitF(netLog, "Ooops - can't find %s\n", data->RoomName);
  539.     return;
  540.  
  541.     }
  542.   if (arg.virtual)
  543.     {
  544.     SetUpForVirtuals(arg.index, &VirtNo, vfn);
  545.     MakeDeCompressedFilename(fn, data->FileName);
  546.     VirtualCopyFileToFile(fn, vfn);
  547.  
  548.     }
  549.   else
  550.     {
  551.     MakeDeCompressedFilename(fn, data->FileName);
  552.     ReadNetRoomFile(arg.index, fn);
  553.  
  554.     }
  555.  
  556.   }
  557. /*
  558. * CacheMessages()
  559. *
  560. * This function is tasked with building cache files as needed.  We loop
  561. * through all the systems in the system list.  Those for which the
  562. * MassTransfer flag is active will cause the system to see if there are
  563. * any messages in the message base that are not in the cache for that
  564. * system.  If any are found, the messages are added to their respective
  565. * files (or create as necessary) and then the compression program is run for
  566. * that particular cache.  Flags must be set appropriately, of course.
  567. */
  568. char CacheUpdated;
  569. void CacheMessages(MULTI_NET_DATA whichNets, char VirtOnly)
  570.   {
  571.   int rover;
  572.   for (rover = 0; rover < cfg.netSize; rover++)
  573.     {
  574.     if ((netTab[rover].ntMemberNets & whichNets))
  575.     CacheSystem(rover, VirtOnly);
  576.  
  577.     }
  578.  
  579.   }
  580. /*
  581. * CacheSystem()
  582. *
  583. * This function caches a single system.  It is separated from CacheMessages()
  584. * so we can cache systems on an individual basis.
  585. */
  586. void CacheSystem(int system, char VirtOnly)
  587.   {
  588.   int CacheRoom(SharedRoom *room, int system, int index, int roomslot, void *d);
  589.   extern void (*NetPrintTarget)(char *format, ...);
  590.   char ArcFileName[60], Files[60], BaseName[40];
  591.   if (!netTab[system].ntflags.MassTransfer) return;
  592.   if (!gotCarrier()) DisableModem(TRUE);
  593.   CacheUpdated = FALSE;
  594.   NetPrintTarget = ToFile;
  595.   EachSharedRoom(system, (VirtOnly) ? NULL : CacheRoom,
  596.   CacheVirtualRoom, NULL);
  597.   if (CacheUpdated)
  598.     {
  599.     putNet(system, &netBuf);
  600.     if (CompAvailable(GetCompression(system)))
  601.       {
  602.       sPrintf(BaseName, NETMSGS, CompExtension(GetCompression(thisNet)));
  603.       NetCacheName(ArcFileName, system, BaseName);
  604.       if (netDebug)splitF(netLog, "ArcFileName:%s\n",ArcFileName);
  605.       NetCacheName(Files, system, CACHED_FILES);
  606.       if (netDebug)splitF(netLog, "Files:%s\n",Files);
  607.       Compress(GetCompression(system), Files, ArcFileName);
  608.       if (access(ArcFileName, 0) != 0)
  609.         {
  610.         sPrintf(msgBuf.mbtext, "Compress failed for %s?",
  611.         netBuf.netName);
  612.         if( logNetResults )splitF(netLog, "ERROR: %s\n", msgBuf.mbtext);
  613.         aideMessage("Net Aide", FALSE);
  614.  
  615.         }
  616.  
  617.       }
  618.     UpdVirtStuff();
  619.  
  620.     }
  621.   if (!gotCarrier()) EnableModem(TRUE);
  622.   NetPrintTarget = mTrPrintf;
  623.  
  624.   }
  625. /*
  626. * CacheRoom()
  627. *
  628. * This caches a room's messages as necessary.
  629. */
  630. int CacheRoom(SharedRoom *room, int system, int index, int roomslot,
  631. void *d)
  632.   {
  633.   extern char PrTransmit;
  634.   char oldNet;
  635.   int MsgCount;
  636.   extern NetInfo NetStyle;
  637.   char work[10], tempNm[3*NAMESIZE], commnd, doit, *name;
  638.   if (roomTab[roomslot].rtlastMessage > room->lastMess &&
  639.   strLen(roomTab[roomslot].rtname))
  640.     {
  641.     if (thisNet != system)
  642.     getNet(system, &netBuf);
  643.     Addressing(system, index, &commnd, &NetStyle.addr1, &NetStyle.addr2,
  644.     &NetStyle.addr3, &name, &doit);
  645.     NetStyle.sendfunc = putFLChar;
  646.     PrTransmit = FALSE;
  647.     sPrintf(work, CACHE_END_NAME, roomslot);
  648.     NetCacheName(tempNm, system, work);
  649.     if ((upfd = safeopen(tempNm, APPEND_ANY)) != NULL)
  650.       {
  651.       oldNet = inNet;
  652.       inNet = NET_CACHE;
  653.       MsgCount = showMessages(NEWoNLY, FALSE,
  654.       room->lastMess, NetRoute);
  655.       inNet = oldNet;
  656.       fclose(upfd);
  657.       SetHighValues(index);
  658.       if (MsgCount == 0 && !GetFA(room->mode))
  659.       unlink(tempNm);
  660.       else if (MsgCount != 0)
  661.         {
  662.         SetFA(netBuf.netRooms[index].mode);
  663.         CacheUpdated = TRUE;
  664.  
  665.         }
  666.  
  667.       }
  668.     PrTransmit = TRUE;
  669.  
  670.     }
  671.   return TRUE;
  672.  
  673.   }
  674. /*
  675. * RecoverMassTransfer()
  676. *
  677. * This function is charged with recovering a mass transfer file that was
  678. * not processed in the last net session due to a crash of some sort.
  679. */
  680. void RecoverMassTransfer(char *line)
  681.   {
  682.   SYS_FILE fn;
  683.   char *colon;
  684.   makeSysName(fn, MAP_FILE, &cfg.netArea);
  685.   RecMassTransfer = TRUE;
  686.   if (netDebug)splitF(netLog, "Recover from:%s\n",fn);
  687.   CheckMap(fn, FALSE);
  688.   if ((colon = strchr(line, ':')) == NULL) return;
  689.   MTCompVal = atoi(colon + 1);
  690.   ReadFastFiles();
  691.  
  692.   }
  693. /*
  694. * UnCacheRoom()
  695. *
  696. * This turns off the cached flag for a given room shared thing.
  697. */
  698. int UnCacheRoom(SharedRoom *room, int system, int index, int roomslot,
  699. void *d)
  700.   {
  701.   if (strLen(roomTab[roomslot].rtname))
  702.     {
  703.     UnSetFA(netBuf.netRooms[index].mode);
  704.     /* this is valid only so long as we uncache on-line, so in case ... */
  705.     if (inNet != NON_NET) SR_Sent[index] = 1;
  706.  
  707.     }
  708.   return TRUE;
  709.  
  710.   }
  711.